package com.lzh.chatnote.user.config.satokenConfig;

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Sa-Token 配置
 *
 * @author lzh
 * 配置每个接口路径的权限
 */
@Configuration
public class SaTokenConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册 Sa-Token 拦截器，定义详细认证规则
        registry.addInterceptor(new SaInterceptor(handler -> {

                    //这里是判断权限判断，并不会不会匹配路径
                    // 指定一条 match 规则
                    SaRouter
                            .match("/**")    // 拦截的 path 列表，可以写多个 */
                            .notMatch("/user/login")
                            // 排除掉的 path 列表，可以写多个
                            .check(r -> StpUtil.checkLogin());        // 要执行的校验动作，可以写完整的 lambda 表达式
                    // 根据路由划分模块，不同模块不同鉴权


                    //1.会话话模块权限和角色校验
                    SaRouter.match("/api/contact/**", r -> {
                        // 用户权限校验逻辑
                        //1.基础权限校验
                        boolean userRole = StpUtil.hasRoleOr("admin", "super_admin");
                        if (!userRole) {
                            //没有权限
                            StpUtil.checkPermission("contact:list");
                        }
                        //2.根据具体路径和HTTP方法进行更细致的权限控制
                        SaRouter.match("/api/contact/**")
                                .matchMethod("POST", "PUT", "DELETE", "PATCH")
                                .check(method ->
                                        //StpUtil.checkRole("admin")
                                        //是否是管理员或者超级管理员
                                        StpUtil.checkRoleOr("admin", "super_admin")
                                );
                    });

                    SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
                    SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
                    SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
                    SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
                })).addPathPatterns("/api/**")
                //作用层面：外部 /api/** 控制哪些请求会进入拦截器，内部 /** 控制在拦截器内如何处理权限校验
                //排除Knife4j文档接口
                .excludePathPatterns(
//                        "/user/isLogin",
//                        "/wx/public/**",
//                        "/user/logout",
//                        "/user/login",          // 显式排除登录接口
//                        "/v2/api-docs/**",                  // Knife4j API 文档
//                        "/swagger-resources/**",             // Knife4j 静态资源
//                        "/webjars/**",                       // Knife4j WebJars
//                        "/doc.html",                         // Knife4j UI 页面
//                        "/error"                           // 错误页面
                )
                .order(Ordered.LOWEST_PRECEDENCE);
        ;
    }


    // Sa-Token 整合 jwt (Simple 简单模式)
    @Bean
    public StpLogic getStpLogicJwt() {
        return new StpLogicJwtForSimple();
    }
}
